import { Router } from 'express';
import { body, param, query } from 'express-validator';
import { authenticateToken, authorizeRole } from '../middleware/auth';
import { validateRequest } from '../middleware/validation';
import { generateSlug } from '../lib/utils';
import { prisma } from '../lib/prisma';

const router = Router();

// 获取分类列表
router.get('/', 
  authenticateToken,
  [
    query('includeChildren').optional().isBoolean(),
    query('includeStats').optional().isBoolean()
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { includeChildren = false, includeStats = false } = req.query;

      // 构建查询条件
      const select: any = {
        id: true,
        name: true,
        description: true,
        slug: true,
        icon: true,
        color: true,
        order: true,
        parentId: true,
        createdAt: true,
        updatedAt: true,
        createdBy: {
          select: {
            id: true,
            username: true
          }
        }
      };

      if (includeChildren === 'true') {
        select.children = {
          select: {
            id: true,
            name: true,
            slug: true,
            icon: true,
            color: true,
            order: true
          },
          orderBy: { order: 'asc' }
        };
      }

      if (includeStats === 'true') {
        select._count = {
          select: {
            knowledgeBases: true,
            children: true
          }
        };
      }

      // 查询分类（只查询顶级分类）
      const categories = await prisma.category.findMany({
        where: { parentId: null },
        select,
        orderBy: { order: 'asc' }
      });

      res.json({
        code: 200,
        message: '获取分类列表成功',
        data: categories
      });
    } catch (error) {
      console.error('获取分类列表失败:', error);
      res.status(500).json({ success: false, error: '获取分类列表失败' });
    }
  }
);

// 获取分类树形结构
router.get('/tree',
  authenticateToken,
  async (req, res) => {
    try {
      // 递归构建分类树
      const buildCategoryTree = async (parentId: string | null = null): Promise<any[]> => {
        const categories = await prisma.category.findMany({
          where: { parentId },
          select: {
            id: true,
            name: true,
            description: true,
            slug: true,
            icon: true,
            color: true,
            order: true,
            parentId: true,
            createdAt: true,
            updatedAt: true,
            _count: {
              select: {
                knowledgeBases: true,
                children: true
              }
            }
          },
          orderBy: { order: 'asc' }
        });

        const tree = [];
        for (const category of categories) {
          const children = await buildCategoryTree(category.id);
          tree.push({
            ...category,
            children
          });
        }

        return tree;
      };

      const categoryTree = await buildCategoryTree();
      res.json({
        code: 200,
        message: '获取分类树成功',
        data: categoryTree
      });
    } catch (error) {
      console.error('获取分类树失败:', error);
      res.status(500).json({ success: false, error: '获取分类树失败' });
    }
  }
);

// 获取单个分类
router.get('/:id',
  authenticateToken,
  [
    param('id').isString().notEmpty().withMessage('分类ID不能为空')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;
      const category = await prisma.category.findUnique({
        where: { id },
        select: {
          id: true,
          name: true,
          description: true,
          slug: true,
          icon: true,
          color: true,
          order: true,
          parentId: true,
          createdAt: true,
          updatedAt: true,
          parent: {
            select: {
              id: true,
              name: true,
              slug: true
            }
          },
          children: {
            select: {
              id: true,
              name: true,
              slug: true,
              icon: true,
              color: true,
              order: true
            },
            orderBy: { order: 'asc' }
          },
          createdBy: {
            select: {
              id: true,
              username: true
            }
          },
          _count: {
            select: {
              knowledgeBases: true
            }
          }
        }
      });

      if (!category) {
        return res.status(404).json({ success: false, error: '分类不存在' });
      }

      res.json({
        code: 200,
        message: '操作成功',
        data: category });
    } catch (error) {
      console.error('获取分类详情失败:', error);
      res.status(500).json({ success: false, error: '获取分类详情失败' });
    }
  }
);

// 创建分类
router.post('/',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    body('name').isString().trim().isLength({ min: 1, max: 100 }).withMessage('分类名称长度必须在1-100个字符之间'),
    body('description').optional().isString().trim(),
    body('icon').optional().isString().trim(),
    body('color').optional().isString().trim().matches(/^#[0-9A-F]{6}$/i).withMessage('颜色格式不正确'),
    body('order').optional().isInt({ min: 0 }).withMessage('排序值必须是非负整数'),
    body('parentId').optional().isString().withMessage('父分类ID格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { name, description, icon, color = '#3B82F6', order = 0, parentId } = req.body;

      // 处理 parentId：空字符串转为 null
      const normalizedParentId = parentId && parentId.trim() !== '' ? parentId : null;

      // 检查父分类是否存在
      if (normalizedParentId) {
        const parentCategory = await prisma.category.findUnique({ where: { id: normalizedParentId } });
        if (!parentCategory) {
          return res.status(400).json({ success: false, error: '父分类不存在' });
        }
      }

      // 生成slug
      const slug = await generateSlug(name, 'category');

      // 创建分类
      const category = await prisma.category.create({
        data: {
          name,
          description,
          slug,
          icon,
          color,
          order,
          parentId: normalizedParentId,
          createdById: req.user.id
        },
        select: {
          id: true,
          name: true,
          slug: true,
          parentId: true,
          createdAt: true
        }
      });

      res.status(201).json({ code: 200, data: category });
    } catch (error) {
      console.error('创建分类失败:', error);
      res.status(500).json({ success: false, error: '创建分类失败' });
    }
  }
);

// 更新分类
router.put('/:id',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    param('id').isString().notEmpty().withMessage('分类ID不能为空'),
    body('name').optional().isString().trim().isLength({ min: 1, max: 100 }).withMessage('分类名称长度必须在1-100个字符之间'),
    body('description').optional().isString().trim(),
    body('icon').optional().isString().trim(),
    body('color').optional().isString().trim().matches(/^#[0-9A-F]{6}$/i).withMessage('颜色格式不正确'),
    body('order').optional().isInt({ min: 0 }).withMessage('排序值必须是非负整数'),
    body('parentId').optional().isString().withMessage('父分类ID格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;
      const updateData = req.body;

      // 检查分类是否存在
      const existingCategory = await prisma.category.findUnique({ where: { id } });
      if (!existingCategory) {
        return res.status(404).json({ success: false, error: '分类不存在' });
      }

      // 如果要更新父分类，检查是否会造成循环引用
      if (updateData.parentId) {
        if (updateData.parentId === id) {
          return res.status(400).json({ success: false, error: '不能将自己设为父分类' });
        }

        // 检查父分类是否存在
        const parentCategory = await prisma.category.findUnique({ where: { id: updateData.parentId } });
        if (!parentCategory) {
          return res.status(400).json({ success: false, error: '父分类不存在' });
        }

        // 检查是否会造成循环引用
        const checkCircularReference = async (categoryId: string, targetId: string): Promise<boolean> => {
          const children = await prisma.category.findMany({
            where: { parentId: categoryId },
            select: { id: true }
          });

          for (const child of children) {
            if (child.id === targetId) return true;
            if (await checkCircularReference(child.id, targetId)) return true;
          }
          return false;
        };

        if (await checkCircularReference(updateData.parentId, id)) {
          return res.status(400).json({ success: false, error: '不能将子分类设为父分类' });
        }
      }

      // 如果更新名称，重新生成slug
      if (updateData.name) {
        updateData.slug = await generateSlug(updateData.name, 'category', id);
      }

      // 更新分类
      const category = await prisma.category.update({
        where: { id },
        data: updateData,
        select: {
          id: true,
          name: true,
          slug: true,
          parentId: true,
          updatedAt: true
        }
      });

      res.json({
        code: 200,
        message: '操作成功',
        data: category });
    } catch (error) {
      console.error('更新分类失败:', error);
      res.status(500).json({ success: false, error: '更新分类失败' });
    }
  }
);

// 删除分类
router.delete('/:id',
  authenticateToken,
  authorizeRole(['ADMIN']),
  [
    param('id').isString().notEmpty().withMessage('分类ID不能为空')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { id } = req.params;

      // 检查分类是否存在
      const existingCategory = await prisma.category.findUnique({ 
        where: { id },
        select: { 
          _count: { 
            children: true, 
            knowledgeBases: true 
          } 
        }
      });
      
      if (!existingCategory) {
        return res.status(404).json({ success: false, error: '分类不存在' });
      }

      // 检查是否有子分类
      if (existingCategory._count.children > 0) {
        return res.status(400).json({ success: false, error: '请先删除子分类' });
      }

      // 检查是否有关联的知识库
      if (existingCategory._count.knowledgeBases > 0) {
        return res.status(400).json({ success: false, error: '请先移除关联的知识库' });
      }

      // 删除分类
      await prisma.category.delete({ where: { id } });

      res.json({ code: 200, message: '分类删除成功' });
    } catch (error) {
      console.error('删除分类失败:', error);
      res.status(500).json({ success: false, error: '删除分类失败' });
    }
  }
);

// 批量更新分类排序
router.patch('/reorder',
  authenticateToken,
  authorizeRole(['ADMIN', 'EDITOR']),
  [
    body('categories').isArray().withMessage('分类数据必须是数组'),
    body('categories.*.id').isString().notEmpty().withMessage('分类ID不能为空'),
    body('categories.*.order').isInt({ min: 0 }).withMessage('排序值必须是非负整数'),
    body('categories.*.parentId').optional().isString().withMessage('父分类ID格式不正确')
  ],
  validateRequest,
  async (req, res) => {
    try {
      const { categories } = req.body;

      // 批量更新分类
      const updatePromises = categories.map((category: any) =>
        prisma.category.update({
          where: { id: category.id },
          data: {
            order: category.order,
            parentId: category.parentId
          }
        })
      );

      await Promise.all(updatePromises);

      res.json({ code: 200, message: '分类排序更新成功' });
    } catch (error) {
      console.error('更新分类排序失败:', error);
      res.status(500).json({ success: false, error: '更新分类排序失败' });
    }
  }
);

// 获取分类统计信息
router.get('/stats/overview',
  authenticateToken,
  authorizeRole(['ADMIN']),
  async (req, res) => {
    try {
      const [
        totalCategories,
        topLevelCategories,
        categoriesWithChildren,
        mostUsedCategories,
        recentCategories
      ] = await Promise.all([
        prisma.category.count(),
        prisma.category.count({ where: { parentId: null } }),
        prisma.category.count({
          where: {
            children: { some: {} }
          }
        }),
        prisma.category.findMany({
          select: {
            id: true,
            name: true,
            color: true,
            _count: {
              select: {
                knowledgeBases: true
              }
            }
          },
          orderBy: {
            knowledgeBases: {
              _count: 'desc'
            }
          },
          take: 10
        }),
        prisma.category.findMany({
          select: {
            id: true,
            name: true,
            slug: true,
            createdAt: true
          },
          orderBy: { createdAt: 'desc' },
          take: 5
        })
      ]);

      res.json({
        code: 200,
        message: '操作成功',
        data: {
          totalCategories,
          topLevelCategories,
          categoriesWithChildren,
          mostUsedCategories,
          recentCategories
        }
      });
    } catch (error) {
      console.error('获取分类统计失败:', error);
      res.status(500).json({ success: false, error: '获取分类统计失败' });
    }
  }
);

export { router as categoryRoutes };
